package org.ethan.lyl;

import com.alibaba.fastjson.JSON;
import org.ethan.lyl.util.StaticStatus;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author:Eason Lau
 * @Date:2018/10/29
 * @Description: 路径分析
 */
public class PathAnalysis {
    static String maxRoute = "";

    /**
     * 获取最终路径
     * @param coordinates
     * @return
     */
    public static List<ArrayIndex> getPath(ImgAnalysis.Coordinate[][] coordinates) {
        maxRoute = "开始";
        max = "";
        ArrayIndex startIndex = new ArrayIndex();
        for (int i = 0; i < coordinates.length; i++) {
            for (int j = 0; j < coordinates[0].length; j++) {
                if(coordinates[i][j].getV()==2)
                    startIndex = new ArrayIndex(i,j);
            }
        }
        doTry(startIndex,coordinates,maxRoute);
        //System.out.println(maxRoute);
        synchronized (StaticStatus.track){
            StaticStatus.track.add("画线路径:"+max);
        }
        List<ArrayIndex> pathArray = new ArrayList<>();
        String[] pathStrArray = max.split("->");
        for(int i=1;i<pathStrArray.length;i++){
            pathArray.add(new ArrayIndex(Integer.parseInt(pathStrArray[i].split(",")[0]),Integer.parseInt(pathStrArray[i].split(",")[1])));
        }
        System.out.println("画线路径：");
        testPrintLink(cloneBinaryArray(coordinates),pathArray);
        return pathArray;
    }

    /**
     * 测试方法，打印路径
     * @param array
     * @param links
     */
    public static void testPrintLink(ImgAnalysis.Coordinate[][] array,List<ArrayIndex> links){
        for(int i=0;i<links.size();i++){
            array[links.get(i).i][links.get(i).j].setV(i+1);
        }
        for (int i=0;i<array.length;i++){
            System.out.print("\n");
            for(int j=0;j<array[i].length;j++){
                System.out.print(String.format("%d\t",array[i][j].getV()));
            }
        }
        System.out.println("");
    }


    /**
     * 下一节点寻路
     * @param currentIndex
     * @param coordinates
     * @param route
     */
    static String  max = "";
    public static void doTry(ArrayIndex currentIndex, ImgAnalysis.Coordinate[][] coordinates, String route) {
        //FIXME 寻路算法出问题了
        //标记为已走过
        coordinates[currentIndex.i][currentIndex.j].setV(-1);
        route += "->" + currentIndex.i + "," + currentIndex.j;
        List<ArrayIndex> childNodeArray = getEnabledChildNode(currentIndex, cloneBinaryArray(coordinates));
        //System.out.println(max.length() >= route.length() ? max:route);
        max = max.length() >= route.length() ? max:route;
        /*if(currentIndex.i==1&&currentIndex.j==0){
        }*/
        //无出口节点，路径终止
        if (childNodeArray.size() == 0) {
            route += "->终止";
            //System.out.println(route);
            maxRoute = route.length() >= maxRoute.length() ? route : maxRoute;
            return;
        } else {
            //统计出口只有1的的节点数
            int nodeNumOfExitingNodeNumIsOne = 0;
            for (ArrayIndex childNode : childNodeArray) {
                if (childNode.getChildNum() == 1) {
                    nodeNumOfExitingNodeNumIsOne++;
                }
            }
            //个数为1，就执行那个，其他剪枝
            if (nodeNumOfExitingNodeNumIsOne == 1) {
                for (ArrayIndex childNode : childNodeArray) {
                    if (childNode.getChildNum() == 1) {
                        doTry(childNode, cloneBinaryArray(coordinates), "" + route);
                    }
                }
            } else if (nodeNumOfExitingNodeNumIsOne == 0) {
                for (ArrayIndex childNode : childNodeArray) {
                    doTry(childNode, cloneBinaryArray(coordinates), "" + route);
                }
            } else if(nodeNumOfExitingNodeNumIsOne == 2){
                for (ArrayIndex childNode : childNodeArray) {
                    if (childNode.getChildNum() == 1) {
                        doTry(childNode, cloneBinaryArray(coordinates), "" + route);
                    }
                }
            }else{
                //多个单出口节点，说明不可用,剪枝
            }
        }
    }

    /**
     * 获取有效的子节点
     */
    public static List<ArrayIndex> getEnabledChildNode(ArrayIndex currentIndex, ImgAnalysis.Coordinate[][] coordinates) {
        List<ArrayIndex> childNodeList = new ArrayList<>();
        if (currentIndex.j + 1 <= coordinates[0].length - 1 && coordinates[currentIndex.i][currentIndex.j + 1].getV() == 1) {
            childNodeList.add(new ArrayIndex(currentIndex.i, currentIndex.j + 1, getEnabledChildNodeNum(currentIndex.i, currentIndex.j + 1, cloneBinaryArray(coordinates))));
        }
        if (currentIndex.j - 1 >= 0 && coordinates[currentIndex.i][currentIndex.j - 1].getV() == 1) {
            childNodeList.add(new ArrayIndex(currentIndex.i, currentIndex.j - 1, getEnabledChildNodeNum(currentIndex.i, currentIndex.j - 1, cloneBinaryArray(coordinates))));
        }
        if (currentIndex.i + 1 <= coordinates.length - 1 && coordinates[currentIndex.i + 1][currentIndex.j].getV() == 1) {
            childNodeList.add(new ArrayIndex(currentIndex.i + 1, currentIndex.j, getEnabledChildNodeNum(currentIndex.i + 1, currentIndex.j, cloneBinaryArray(coordinates))));
        }
        if (currentIndex.i - 1 >= 0 && coordinates[currentIndex.i - 1][currentIndex.j].getV() == 1) {
            childNodeList.add(new ArrayIndex(currentIndex.i - 1, currentIndex.j, getEnabledChildNodeNum(currentIndex.i - 1, currentIndex.j, cloneBinaryArray(coordinates))));
        }
        return childNodeList;
    }

    /**
     * 统计节点的出口数
     *
     * @param i
     * @param j
     * @param coordinates
     * @return
     */
    public static int getEnabledChildNodeNum(int i, int j, ImgAnalysis.Coordinate[][] coordinates) {
        coordinates[i][j].setV(-1);
        int num = 0;
        if (j + 1 <= coordinates[0].length - 1 && coordinates[i][j + 1].getV() == 1) {
            num++;
        }
        if (j - 1 >= 0 && coordinates[i][j - 1].getV() == 1) {
            num++;
        }
        if (i + 1 <= coordinates.length - 1 && coordinates[i + 1][j].getV() == 1) {
            num++;
        }
        if (i - 1 >= 0 && coordinates[i - 1][j].getV() == 1) {
            num++;
        }
        return num;
    }


    public static class ArrayIndex {
        public int i;
        public int j;
        public int childNum;

        public ArrayIndex() {
        }

        public ArrayIndex(int i, int j) {
            this.i = i;
            this.j = j;
        }

        public ArrayIndex(int i, int j, int childNum) {
            this.i = i;
            this.j = j;
            this.childNum = childNum;
        }

        public int getI() {
            return i;
        }

        public void setI(int i) {
            this.i = i;
        }

        public int getJ() {
            return j;
        }

        public void setJ(int j) {
            this.j = j;
        }

        public int getChildNum() {
            return childNum;
        }

        public void setChildNum(int childNum) {
            this.childNum = childNum;
        }
    }

    /**
     * 克隆数组
     *
     * @param array
     * @return
     */
    public static ImgAnalysis.Coordinate[][] cloneBinaryArray(ImgAnalysis.Coordinate[][] array) {
        ImgAnalysis.Coordinate[][] cloneArray = new ImgAnalysis.Coordinate[array.length][array[0].length];
        for (int i = 0; i < array.length; i++) {
            for(int j=0;j<array[i].length;j++){
                cloneArray[i][j] = JSON.parseObject(JSON.toJSONString(array[i][j]),ImgAnalysis.Coordinate.class);
            }
            //cloneArray[i] = array[i].clone();
        }
        return cloneArray;
    }
}
